﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Text;
using System.Threading.Tasks;

namespace SimdTest2.Methods
{
    [Algorithm(true, AlgorithmType.Eight)]
    public unsafe class EightMethod : AlgorithmBase
    {
        public EightMethod(int row, int col) : base(row, col)
        {
        }
        byte[] _buffer;
        byte[] _buffer_Sourse;
        int Width;
        float color_m = 57;
        float color_h = 69;
        protected override void CreateData()
        {
            State_MeltROI_L_Angle40 = new Rectangle(363, 135, 228, 873);
            _buffer = new byte[_size];
            _buffer_Sourse = new byte[_size];
            Random random = new Random();
            random.NextBytes(_buffer);
            Array.Copy(_buffer, _buffer_Sourse, _size);

            color_mV = Vector128.Create((byte)color_m);
            color_hV = Vector128.Create((byte)color_h);
            color_mhV =Vector128.Create((byte)((double)255 / (color_h - color_m)));
        }
        private Rectangle State_MeltROI_L_Angle40;
        protected override void OrdinaryMethod()
        {
            for (int y = State_MeltROI_L_Angle40.Y; y < State_MeltROI_L_Angle40.Y + State_MeltROI_L_Angle40.Height; y++)
            {
                for (int x = State_MeltROI_L_Angle40.X; x < State_MeltROI_L_Angle40.X + State_MeltROI_L_Angle40.Width; x++)
                {
                    float cha = (float)(_buffer_Sourse[y * Width + x] - color_m);
                    if (cha < 0 && cha >= -10)
                    {
                        cha = 0;
                    }
                    if (cha < -10)
                    {
                        cha = -10000;
                    }
                    //线性比例变换
                    int gray = (int)(0 + cha / (float)(color_h - color_m) * 255);
                    if (gray > 255)
                    {
                        gray = 255;
                    }
                    if (gray < 0)
                    {
                        gray = 0;
                    }
                    _buffer[y * Width + x] = (byte)gray;
                }
            }
        }
        Vector128<byte> color_mV;
        Vector128<byte> color_hV;
        Vector128<byte> color_mhV;
        protected override void SimdMethod()
        {
            fixed (byte* bptr = _buffer, sptr = _buffer_Sourse)
            {
                int vsize = Vector128<byte>.Count;
                for (int y = State_MeltROI_L_Angle40.Y; y < State_MeltROI_L_Angle40.Y + State_MeltROI_L_Angle40.Height; y++)
                {
                    int yw = y * Width;
                    for (int x = State_MeltROI_L_Angle40.X; x < State_MeltROI_L_Angle40.X + State_MeltROI_L_Angle40.Width; x += vsize)
                    {
                        int t = yw + x;
                        Vector128<byte> chaV = Sse2.SubtractSaturate(*(Vector128<byte>*)(sptr + t), color_mV);
                        var garyV = chaV * color_mhV;
                        Sse2.Store(bptr + t, garyV);
                    }
                }
            }
        }
    }
}
